package com.binfast.codegen.services.impl;

import cn.hutool.core.util.StrUtil;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import com.binfast.codegen.config.GenCodeConfig;
import com.binfast.codegen.gen.HtmlGen;
import com.binfast.codegen.gen.JSGen;
import com.binfast.codegen.gen.MavenProjectTarget;
import com.binfast.codegen.gen.genPoJo;
import com.binfast.codegen.gen.model.Attribute;
import com.binfast.codegen.gen.model.Entity;
import com.binfast.codegen.model.params.generate.GenerateParam;
import com.binfast.codegen.services.GenerateServ;
import org.beetl.sql.core.JavaType;
import org.beetl.sql.core.SQLManager;
import org.beetl.sql.core.db.ColDesc;
import org.beetl.sql.core.db.TableDesc;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Set;

@Service
public class GenerateServImpl implements GenerateServ {
    private static final Log log = LogFactory.get();

    @Autowired
    GenCodeConfig genCodeConfig;
    @Autowired
    SQLManager sqlManager;

    @Override
    public String generateAllCode(GenerateParam param) {
        generateJavaCode(param);
        String routes = generatePaegCode(param);
        return routes;
    }

    @Override
    public Boolean generateJavaCode(GenerateParam param) {
        genPoJo genPoJo = new genPoJo(
                genCodeConfig.getPackageName()
                ,genCodeConfig.getProjectSrcPath()
                ,genCodeConfig.getProjectResourcePath()
                ,genCodeConfig.getServicePath()
                ,genCodeConfig.getServiceResourcePath()
                ,genCodeConfig.getServiceName()
                ,genCodeConfig.getDtoParamPath()
                ,genCodeConfig.getDtoParamResourcePath()
                ,genCodeConfig.getDtoParamName()
                ,genCodeConfig.getAdminPath()
                ,genCodeConfig.getDaoSrcPath()
                ,genCodeConfig.getDaoResourcePath()
                ,genCodeConfig.getDaoPath());
        genPoJo.genCode(param.getPreTableName(), param.getTableName(),param.getTableTitle(),sqlManager);
        return null;
    }

    @Override
    public String generatePaegCode(GenerateParam param) {
        Entity entity = getEntityInfo(param.getTableName(),param.getTableTitle());
        MavenProjectTarget target = new MavenProjectTarget(entity, genCodeConfig.getPackageName(),genCodeConfig.getView(),genCodeConfig.getJs());
        HtmlGen htmlGen = new HtmlGen();
        htmlGen.make(target,entity);
        JSGen jsGen = new JSGen();
        jsGen.make(target,entity);

        String routes = genRouterConsole(entity);
        return routes;
    }

    private Entity getEntityInfo(String tableName,String tableTitle) {
        TableDesc tableDesc = this.sqlManager.getMetaDataManager().getTable(tableName);
        String className = this.sqlManager.getNc().getClassName(tableDesc.getName());

        Set<String> cols = tableDesc.getCols();
        ArrayList<Attribute> attributes = new ArrayList<>();
        Entity entity = new Entity();

        cols.stream().forEach(m -> {
            Attribute attribute = new Attribute();
            String code = (String) m;
            ColDesc desc = tableDesc.getColDesc(code);
            attribute.setComment(desc.remark);
            String attrName = this.sqlManager.getNc().getPropertyName((Class)null, desc.colName);
            attribute.setName(attrName);
            attribute.setDisplayName(desc.remark);
            attribute.setColName(desc.colName);
//            attr.put("methodName", this.getMethodName(attrName));
            boolean isKey = tableDesc.getIdNames().contains(desc.colName);
            attribute.setId(isKey);
            if(isKey) entity.setIdAttribute(attribute);
            String type = JavaType.getType(desc.sqlType, desc.size, desc.digit);
            if (type.equals("Double"))  type = "BigDecimal";
            if (type.equals("Timestamp"))  type = "Date";
            attribute.setJavaType(type);
//            attr.put("desc", desc);
            attributes.add(attribute);
        });

        entity.setCode(StrUtil.lowerFirst(className));
        entity.setName(className);
        entity.setDisplayName(tableTitle);
        entity.setTableName(tableName);
//        entity.setComment();

        entity.setList(attributes);

        return entity;
    }

    String genRouterConsole (Entity entity) {
        StringBuilder stringBuilder = new StringBuilder("");
        stringBuilder.append("{ </br>");
        stringBuilder.append("&nbsp;&nbsp; path: '/").append(entity.getCode()).append("', </br>");
        stringBuilder.append("&nbsp;&nbsp; component: Layout,</br>");
        stringBuilder.append("&nbsp;&nbsp; redirect: '/").append(entity.getCode()).append("/").append(entity.getCode()+"List").append("', </br>");
        stringBuilder.append("&nbsp;&nbsp; name: '").append(entity.getName()).append("', </br>");
        stringBuilder.append("&nbsp;&nbsp; children: [ </br>");
        stringBuilder.append("&nbsp;&nbsp;&nbsp;&nbsp; { </br>");
        stringBuilder.append("&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; path: '/").append(entity.getCode()+"List").append("', </br>");
        stringBuilder.append("&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; component: () => import('@/views/").append(entity.getCode()).append("/list'), </br>");
        stringBuilder.append("&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; name: '").append(entity.getName()+"List").append("', </br>");
        stringBuilder.append("&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; meta: { title: '").append(entity.getDisplayName()).append("', icon: 'el-icon-date', noCache: true } </br>");
        stringBuilder.append("&nbsp;&nbsp;&nbsp;&nbsp; },{ </br>");
        stringBuilder.append("&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; hidden: true, </br>");
        stringBuilder.append("&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; path: '").append(entity.getCode()).append("Detail', </br>");
        stringBuilder.append("&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; name: '").append(entity.getName()).append("Detail', </br>");
        stringBuilder.append("&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; component: () => import('@/views/").append(entity.getCode()).append("/detail'), </br>");
        stringBuilder.append("&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; meta: { title: '").append(entity.getDisplayName()).append("详情', icon: 'detail' }, </br>");
        stringBuilder.append("&nbsp;&nbsp;&nbsp;&nbsp; }] </br>");
        stringBuilder.append("}, </br>");
        stringBuilder.append("</br>");

        System.out.println(stringBuilder.toString());
        return stringBuilder.toString();
    }
}
